package com.icesoft.system.safe.utils;

import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.generators.RSAKeyPairGenerator;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.crypto.params.RSAKeyGenerationParameters;
import org.bouncycastle.crypto.util.PrivateKeyFactory;
import org.bouncycastle.crypto.util.PrivateKeyInfoFactory;
import org.bouncycastle.crypto.util.PublicKeyFactory;
import org.bouncycastle.crypto.util.SubjectPublicKeyInfoFactory;
import org.bouncycastle.openssl.PEMException;
import org.bouncycastle.openssl.PEMKeyPair;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;

import java.io.IOException;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.util.Base64;

public class KeyPairUtils {

	public static KeyPair createKeyPair() throws IOException {
		return convert(createPemKeyPair());
	}

	public static KeyPair convert(PEMKeyPair pemKeyPair) throws PEMException {
		return new JcaPEMKeyConverter().getKeyPair(pemKeyPair);
	}

	/**
	 * 生成RSA密钥对
	 */
	public static PEMKeyPair createPemKeyPair() throws IOException {
		//生成密钥对
		RSAKeyPairGenerator rsaKeyPairGenerator = new RSAKeyPairGenerator();
		RSAKeyGenerationParameters rsaKeyGenerationParameters = new RSAKeyGenerationParameters(BigInteger.valueOf(3), new SecureRandom(), 1024, 25);
		rsaKeyPairGenerator.init(rsaKeyGenerationParameters);//初始化参数
		AsymmetricCipherKeyPair keyPair = rsaKeyPairGenerator.generateKeyPair();
		AsymmetricKeyParameter publicKeyParam = keyPair.getPublic();//公钥
		AsymmetricKeyParameter privateKeyParam = keyPair.getPrivate();//私钥
		SubjectPublicKeyInfo subjectPublicKeyInfo = SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(publicKeyParam);
		PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.createPrivateKeyInfo(privateKeyParam);
		return new PEMKeyPair(subjectPublicKeyInfo, privateKeyInfo);
	}

	public static PrivateKey getPrivateKey(String privateKeyBase64) {
		byte[] buffer = Base64.getMimeDecoder().decode(privateKeyBase64);
		try {
			return getPrivateKey(buffer);
		} catch (IOException e) {
			throw new IllegalArgumentException("密钥读取错误", e);
		}
	}

	public static PrivateKey getPrivateKey(byte[] privateInfoByte) throws IOException {
		AsymmetricKeyParameter priKey = PrivateKeyFactory.createKey(privateInfoByte);
		PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.createPrivateKeyInfo(priKey);
		return new JcaPEMKeyConverter().getPrivateKey(privateKeyInfo);
	}

	public static PublicKey getPublicKey(String publicKeyBase64) {
		byte[] buffer = Base64.getMimeDecoder().decode(publicKeyBase64);
		try {
			return getPublicKey(buffer);
		} catch (IOException e) {
			throw new IllegalArgumentException("公钥读取错误", e);
		}
	}

	public static PublicKey getPublicKey(byte[] publicInfoByte) throws IOException {
		AsymmetricKeyParameter priKey = PublicKeyFactory.createKey(publicInfoByte);
		SubjectPublicKeyInfo subjectPublicKeyInfo = SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(priKey);
		return new JcaPEMKeyConverter().getPublicKey(subjectPublicKeyInfo);
	}
}
